/// <license>
/// Copyright (c) 2002-2008, DotNetNuke Corporation
/// All rights reserved
///
/// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
/// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
/// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
/// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
/// of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
/// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
/// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
/// DEALINGS IN THE SOFTWARE.
/// </license>

#region Using Statements

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI.WebControls;

using Globals = DotNetNuke.Common.Globals;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Entities.Modules.Actions;
using DotNetNuke.Security;
using DotNetNuke.UI.Utilities;

using DotNetNuke.Modules.Articles.Common;
using DotNetNuke.Modules.Articles.UI.Editors;
using DotNetNuke.Modules.Articles.UI.Controls;

using Constants = DotNetNuke.Modules.Articles.Common.Constants;
using DotNetNuke.ModuleToolkit.Modules.Skinning;
using DotNetNuke.ModuleToolkit.Modules.Skinning.SkinObjects;
using DotNetNuke.ModuleToolkit.Common;

#endregion

namespace DotNetNuke.Modules.Articles.Framework
{

    /// -----------------------------------------------------------------------------
    /// <summary>
    /// The ArticlesModuleBase Class provides a Base class for all Articles Module
    /// Controls
    /// </summary>
    /// <history>
    /// 	[cnurse]	01/31/2006	created
    /// </history>
    /// -----------------------------------------------------------------------------
    public class ArticlesModuleBase : SkinnablePortalModuleBase
    {

        #region Private Members

        private int _ArticleId = Null.NullInteger;
        private List<ArticleInfo> _Articles;
        private List<ArticleEditor> ArticleEditors;
        private ArticleInfo _CurrentArticle;
        private ArticleInfo _PublishedArticle;

        private int _SectionId = Null.NullInteger;
        private SectionInfo _Section;
        private List<SectionInfo> _Sections;
        private List<SectionEditor> SectionEditors;

        private List<SettingsEditor> SettingsEditors;

        #endregion

        #region Protected Properties

        /// <summary>
        /// gets the Article Settings for this module
        /// </summary>
        protected ArticleSettings ArticleSettings
        {
            get { return ArticleSettings.GetSettings(ModuleId, TabModuleId); }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets the default article
        /// </summary>
        /// <history>
        /// 	[cnurse]	08/01/2006	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected int DefaultArticle
        {
            get
            {
                //Get the default article from the Settings
                int defaultArticle = ArticleSettings.DefaultArticle;

                //if no default article get the first article
                if (defaultArticle == Null.NullInteger)
                {
                    List<ArticleInfo> aticles = ArticleController.GetAllArticles(ModuleId);
                    if (aticles.Count > 0)
                    {
                        defaultArticle = aticles[0].ArticleId;
                    }
                }
                return defaultArticle;
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets the default section
        /// </summary>
        /// <history>
        /// 	[cnurse]	08/01/2006	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected int DefaultSection
        {
            get
            {
                //Get the default section from the Settings
                int defaultSection = ArticleSettings.DefaultSection;

                //if no default section get the first section
                if (defaultSection == Null.NullInteger)
                {
                    List<SectionInfo> sections = SectionController.GetSections(ModuleId);
                    if (sections.Count > 0)
                    {
                        defaultSection = sections[0].SectionId;
                    }
                }
                return defaultSection;
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets the default view
        /// </summary>
        /// <history>
        /// 	[cnurse]	08/01/2006	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected DefaultView DefaultView
        {
            get { return ArticleSettings.DefaultView; }
        }

        #endregion

        #region Public Properties

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets and sets the Article
        /// </summary>
        /// <history>
        /// 	[cnurse]	01/31/2006	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        public ArticleInfo Article
        {
            get 
            {
                ArticleInfo _Article;
                if (IsEditMode)
                {
                    _Article = CurrentArticle;
                }
                else
                {
                    if (PublishedArticle == null && ((CurrentArticle != null && CurrentArticle.CreatedByUser == UserId) || HasModeratePermission))
                    {
                        //Current Article hasn't been published yet
                        _Article = CurrentArticle;
                    }
                    else
                    {
                        _Article = PublishedArticle;
                    }
                }
                return _Article; 
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets and sets the ArticleId
        /// </summary>
        /// <history>
        /// 	[cnurse]	01/31/2006	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        public int ArticleId
        {
            get { return _ArticleId; }
            set { _ArticleId = value; }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets and sets the List of Articles
        /// </summary>
        /// <history>
        /// 	[cnurse]	01/31/2006	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        public List<ArticleInfo> Articles
        {
            get 
            {
                if (_Articles == null)
                    LoadArticles();
                return _Articles; 
            }
            set { _Articles = value; }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets whether the current user has permission to delete the current Article
        /// </summary>
        /// <history>
        /// 	[cnurse]	09/10/2007	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        public bool CanDeleteArticle
        {
            get
            {
                bool canDelete = false;

                //Users with Article Delete permission can Delete articles
                if (HasDeletePermission)
                    canDelete = true;

                //Article Creators have permission to Delete their own articles (if enabled in Setting)
                bool creatorCanDelete = ArticleSettings.CreatorCanDelete;

                if (creatorCanDelete && HasCreatePermission && (Article != null && (Article.CreatedByUser == UserId)))
                    canDelete = true;

                return canDelete;
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets whether the current user has permission to edit the current Article
        /// </summary>
        /// <history>
        /// 	[cnurse]	09/06/2007	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        public bool CanEditArticle
        {
            get
            {
                bool canEdit = false;

                //Article Moderators have permission to Edit articles that have been submitted
                if (UseModeration)
                {
                    if (HasModeratePermission && (Article != null && Article.Status != PublishedStatus.Draft))
                        canEdit = true;
                }
                else
                {
                    if (HasModeratePermission && Article != null)
                        canEdit = true;
                }

                //Article Creators have permission to Edit their own articles
                if (HasCreatePermission && (Article != null && (Article.CreatedByUser == UserId)))
                    canEdit = true;

                return canEdit;
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets and sets the Current Version of the Article
        /// </summary>
        /// <history>
        /// 	[cnurse]	09/11/2007	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        public ArticleInfo CurrentArticle
        {
            get
            {
                if (_CurrentArticle == null)
                {
                    if (ArticleId != Null.NullInteger)
                    {
                        //Get the Current version of the Article to display 
                        _CurrentArticle = ArticleController.GetArticle(ArticleId);
                    }
                }
                return _CurrentArticle;
            }
            set { _CurrentArticle = value; }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets whether the module is in Add Mode
        /// </summary>
        /// <history>
        /// 	[cnurse]	09/10/2007	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        public override bool IsAddMode
        {
            get 
            {
                bool isAddMode;
                switch (Mode)
                {
                    case Constants.KEY_AddArticle:
                    case Constants.KEY_AddSection:
                        isAddMode = true;
                        break;
                    default:
                        isAddMode = false;
                        break;
                }
                return isAddMode; 
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets whether the module is in Edit Mode
        /// </summary>
        /// <history>
        /// 	[cnurse]	09/10/2007	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        public override bool IsEditMode
        {
            get
            {
                bool isEditMode;
                switch (Mode)
                {
                    case Constants.KEY_AddArticle:
                    case Constants.KEY_AddSection:
                    case Constants.KEY_EditArticle:
                    case Constants.KEY_EditSection:
                        isEditMode = true;
                        break;
                    default:
                        isEditMode = false;
                        break;
                }
                return isEditMode;
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets the custom Module Actions
        /// </summary>
        /// <history>
        /// 	[cnurse]	04/01/2006	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        public override ModuleActionCollection ModuleActions
        {
            get
            {
                ModuleActionCollection Actions = new ModuleActionCollection();

                //Only display add/edit/delete if no Mode or Mode is MyArticles or Moderate
                if (Mode != Constants.KEY_AddArticle && Mode != Constants.KEY_EditArticle && Mode != Constants.KEY_AddSection && Mode != Constants.KEY_EditSection)
                {
                    //Add the New menu items
                    if (IsEditable)
                    {
                        ModuleAction addRoot = new ModuleAction(GetNextActionID(), LocalizeString(Constants.ACTION_Add), "", "", Constants.ACTIONIMAGE_Add, "", "", false, SecurityAccessLevel.Edit, true);
                        addRoot.Actions.Add(GetNextActionID(), LocalizeString(Constants.ACTION_NewSection), ModuleActionType.AddContent, "", "", ArticleURL(TabId, Null.NullInteger, SectionId, Constants.KEY_AddSection), false, SecurityAccessLevel.Edit, true, false);
                        addRoot.Actions.Add(GetNextActionID(), LocalizeString(Constants.ACTION_NewArticle), ModuleActionType.AddContent, "", "", ArticleURL(TabId, Null.NullInteger, SectionId, Constants.KEY_AddArticle), false, SecurityAccessLevel.Edit, true, false);
                        Actions.Add(addRoot);

                        Actions.Add(new ModuleAction(GetNextActionID(), "~", ""));
                    }
                    else if (HasCreatePermission)
                    {
                        //Add Add Article menu Item
                        Actions.Add(GetNextActionID(), LocalizeString(Constants.ACTION_AddArticle), ModuleActionType.AddContent, "", Constants.ACTIONIMAGE_Add, ArticleURL(TabId, Null.NullInteger, SectionId, Constants.KEY_AddArticle), false, SecurityAccessLevel.View, true, false);
                        Actions.Add(new ModuleAction(GetNextActionID(), "~", ""));
                    }

                    if (ArticleId > Null.NullInteger && CanEditArticle && !IsEditMode)
                        //Add Edit Article menu Item
                        Actions.Add(GetNextActionID(), LocalizeString(Constants.ACTION_EditArticle), Constants.ACTION_EditArticle, "", Constants.ACTIONIMAGE_Edit, ArticleURL(TabId, ArticleId, Constants.KEY_EditArticle), false, SecurityAccessLevel.View, true, false);
                    else if (SectionId > Null.NullInteger)
                        //Add Delete Section menu Item
                        Actions.Add(GetNextActionID(), LocalizeString(Constants.ACTION_EditSection), Constants.ACTION_EditSection, "", Constants.ACTIONIMAGE_Edit, ArticleURL(TabId, Null.NullInteger, SectionId, Constants.KEY_EditSection), false, SecurityAccessLevel.Edit, IsEditable, false);

                    if (ArticleId > Null.NullInteger && CanDeleteArticle && !IsEditMode)
                        //Add Delete Article menu Item
                        Actions.Add(GetNextActionID(), LocalizeString(Constants.ACTION_DeleteArticle), Constants.ACTION_DeleteArticle, "", Constants.ACTIONIMAGE_Delete, "", "confirm('" + ClientAPI.GetSafeJSString(LocalizeString(Constants.CONFIRM_DeleteArticle)) + "')", false, SecurityAccessLevel.View, true, false);
                    else if (SectionId > Null.NullInteger)
                        //Add Delete Section menu Item
                        Actions.Add(GetNextActionID(), LocalizeString(Constants.ACTION_DeleteSection), Constants.ACTION_DeleteSection, "", Constants.ACTIONIMAGE_Delete, "", "confirm('" + ClientAPI.GetSafeJSString(LocalizeString(Constants.CONFIRM_DeleteSection)) + "')", false, SecurityAccessLevel.Edit, IsEditable, false);

                    Actions.Add(new ModuleAction(GetNextActionID(), "~", ""));
                }

                if (HasCreatePermission)
                    //Add My Articles
                    Actions.Add(GetNextActionID(), LocalizeString(Constants.ACTION_MyArticles), Constants.ACTION_MyArticles, "", Constants.ACTIONIMAGE_MyArticles, ArticleURL(Constants.KEY_MyArticles), false, SecurityAccessLevel.View, true, false);

                if (HasModeratePermission && ArticleSettings.GetSettings(ModuleId, TabModuleId).UseModeration)
                    //Add Moderation List
                    Actions.Add(GetNextActionID(), LocalizeString(Constants.ACTION_Moderate), Constants.ACTION_Moderate, "", Constants.ACTIONIMAGE_Moderate, ArticleURL(Constants.KEY_Moderate), false, SecurityAccessLevel.View, true, false);

                Actions.AddRange(base.ModuleActions);
                return Actions;
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets and sets the Published Version of the Article
        /// </summary>
        /// <history>
        /// 	[cnurse]	09/11/2007	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        public ArticleInfo PublishedArticle
        {
            get
            {
                if (_PublishedArticle == null)
                {
                    if (ArticleId != Null.NullInteger)
                    {
                        //Get the Published version of the Article to display 
                        _PublishedArticle = ArticleController.GetPublishedArticle(ArticleId);
                    }
                }
                return _PublishedArticle;
            }
            set { _PublishedArticle = value; }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets the return url
        /// </summary>
        /// <history>
        /// 	[cnurse]	10/31/2007	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        public override string ReturnURL
        {
            get
            {
                string param = Null.NullString;

                //If scope is of form "Scope1_Scope2" then new Scope is Scope1 and mode is Scope2
                //Otherwise scope is "" and mode = Scope
                if (!String.IsNullOrEmpty(Scope))
                {
                    if (Scope.Contains("_"))
                    {
                        int delimiter = Scope.LastIndexOf("_");
                        string mode = Scope.Substring(delimiter + 1);
                        string scope = Scope.Remove(delimiter);
                        param = Constants.PARAM_Scope + "=" + scope;
                        param += "&" + Constants.PARAM_Mode + "=" + mode;
                    }
                    else
                    {
                        param += Constants.PARAM_Mode + "=" + Scope;
                    }
                }

                if (Scope.Contains(Constants.KEY_ViewSection))
                    param += "&" + Constants.PARAM_SectionId + "=" + SectionId.ToString();
                if (Scope.Contains(Constants.KEY_ViewArticle) || Scope.Contains(Constants.KEY_EditArticle))
                    param += "&" + Constants.PARAM_ArticleId + "=" + ArticleId.ToString();


                return Globals.NavigateURL(TabId, "", param);
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets and sets the SectionId
        /// </summary>
        /// <history>
        /// 	[cnurse]	01/31/2006	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        public int SectionId
        {
            get { return _SectionId; }
            set { _SectionId = value; }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets and sets the Section
        /// </summary>
        /// <history>
        /// 	[cnurse]	01/31/2006	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        public SectionInfo Section
        {
            get 
            {
                if (_Section == null)
                    LoadSection();
                return _Section; 
            }
            set { _Section = value; }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets the sections associated with the control
        /// </summary>
        /// <history>
        /// 	[cnurse]	03/30/2006	created
        /// </history>
        /// -----------------------------------------------------------------------------
        public List<SectionInfo> Sections
        {
            get
            {
                if (_Sections == null)
                    LoadSections();
                return _Sections;
            }
            set { _Sections = value; }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets whether the Moderation is enabled
        /// </summary>
        /// <history>
        ///     [cnurse]  10/10/2007  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        public bool UseModeration
        {
            get { return ArticleSettings.UseModeration; }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The TabId of the Page to display "Detail"
        /// </summary>
        /// <history>
        /// 	[cnurse]	01/31/2006	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        public int ViewTabId
        {
            get
            {
                int _TabId = TabId;
                if ( Settings[Constants.SETTING_DetailTabId] != null)
                    _TabId = (int)Settings[Constants.SETTING_DetailTabId];
                return _TabId;
            }
        }

        #endregion

        #region Private Methods

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The AddArticle method sets the module up to add an article
        /// </summary>
        /// <history>
        ///     [cnurse]    09/06/2007  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void AddArticle()
        {
            if (HasCreatePermission)
            {
                //Load the EditArticle View/Skin
                SetView(Constants.VIEW_EditArticle);

                //Initialise new ArticleInfo
                ArticleInfo addArticle = new ArticleInfo();
                addArticle.ArticleId = Null.NullInteger;
                addArticle.SectionId = Section.SectionId;
                addArticle.VersionNo = 1;
                addArticle.Title = LocalizeString(Constants.KEY_NewArticle);

                //Default Author to current User
                addArticle.Author = UserInfo.DisplayName;

                foreach (ArticleEditor editor in ArticleEditors)
                {
                    editor.Article = addArticle;
                    editor.DataBind();
                }
            }
            else
                //Load the AccessDenied View
                SetView(Constants.VIEW_AccessDenied);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The AddArticleEditor method adds an ArticleEditor to the Article Editors Collection
        /// </summary>
        /// <history>
        ///     [cnurse]    07/21/2006  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void AddArticleEditor(ArticleEditor editor)
        {
            if (ArticleEditors == null)
                ArticleEditors = new List<ArticleEditor>();
            ArticleEditors.Add(editor);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The AddSectionEditor method adds a SectionEditor to the Section Editors Collection
        /// </summary>
        /// <history>
        ///     [cnurse]    07/21/2006  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void AddSectionEditor(SectionEditor editor)
        {
            if (SectionEditors == null)
                SectionEditors = new List<SectionEditor>();
            SectionEditors.Add(editor);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The AddSettingsEditor method adds a SettingsEditor to the Settings Editors Collection
        /// </summary>
        /// <history>
        ///     [cnurse]    01/01/2008  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void AddSettingsEditor(SettingsEditor editor)
        {
            if (SettingsEditors == null)
                SettingsEditors = new List<SettingsEditor>();
            SettingsEditors.Add(editor);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The CancelArticle method aborts the editing of an article
        /// </summary>
        /// <history>
        ///     [cnurse]    01/03/2008  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void CancelArticle()
        {
            Response.Redirect(ReturnURL, true);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The CancelSection method aborts the editing of a section
        /// </summary>
        /// <history>
        ///     [cnurse]    09/07/2007  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void CancelSection()
        {
            Response.Redirect(ReturnURL, true);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The ConfigureModule method loads the Configure Module View
        /// </summary>
        /// <history>
        ///     [cnurse]    01/02/2008  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void ConfigureModule()
        {
            if (IsEditable)
            {
                //Load the Configure Module View/Skin
                SetView(Constants.VIEW_ConfigureModule);

                foreach (SettingsEditor editor in SettingsEditors)
                {
                    editor.ArticleSettings = ArticleSettings;
                    editor.LocalResourceFile = Constants.LOCALIZATION_ResourceFile;
                    editor.DataBind();
                }
            }
            else
                //Load the AccessDenied View
                SetView(Constants.VIEW_AccessDenied);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The DeleteArticle method deletes the current article
        /// </summary>
        /// <history>
        ///     [cnurse]    10/26/2007  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void DeleteArticle()
        {
            DeleteArticle(Article);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The DeleteArticle method deletes an article
        /// </summary>
        /// <history>
        ///     [cnurse]    07/30/2006  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void DeleteArticle(ArticleInfo deleteArticle)
        {
            //Save the Updated Article
            ArticleController.DeleteArticle(deleteArticle, UserId);

            //Redirect back to page
            Response.Redirect(ReturnURL, true);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The DeleteSection method delete the current section
        /// </summary>
        /// <history>
        ///     [cnurse]    04/19/2006  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void DeleteSection()
        {
            //Save the Updated Section
            SectionController.DeleteSection(Section, UserId);

            //Redirect back to page
            Response.Redirect(ReturnURL, true);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The EditArticle method sets the module up to edit an article
        /// </summary>
        /// <history>
        ///     [cnurse]    05/21/2006  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void EditArticle()
        {
            if (CanEditArticle)
            {
                //Load the EditArticle View/Skin
                SetView(Constants.VIEW_EditArticle);

                foreach (ArticleEditor editor in ArticleEditors)
                {
                    editor.Article = Article;
                    editor.DataBind();
                }
            }
            else
                //Load the AccessDenied View
                SetView(Constants.VIEW_AccessDenied);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The EditSection method sets the module up to edit a section
        /// </summary>
        /// <history>
        ///     [cnurse]    05/21/2006  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void EditSection()
        {
            if (this.IsEditable)
            {
                //Load the EditSection View/Skin
                SetView(Constants.VIEW_EditSection);

                SectionInfo editSection;

                if (IsAddMode)
                {
                    editSection = new SectionInfo();

                    //Initialise new SectionInfo
                    editSection.SectionId = Null.NullInteger;
                    editSection.Name = LocalizeString(Constants.KEY_NewSection);

                    //Default parent Section to current Section
                    editSection.ParentSectionId = Section.SectionId;
                }
                else
                    editSection = Section;

                foreach (SectionEditor editor in SectionEditors)
                {
                    editor.Section = editSection;
                    editor.DataBind();
                }
            }
            else
            if (IsAddMode)
                //Load the AccessDenied View
                SetView(Constants.VIEW_AccessDenied);
            else
                //Load the ViewSection View/Skin
                SetView(Constants.VIEW_ViewSection);
    }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The loadArticles method gets a List of Articles from the Data Store
        /// </summary>
        /// <history>
        ///     [cnurse]    02/13/2006  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void LoadArticles()
        {
            if (SectionId == Null.NullInteger)
                Articles = ArticleController.GetCurrentArticles(ModuleId);
            else
                Articles = ArticleController.GetArticlesBySection(ModuleId, SectionId);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The loadSection method gets a section from the Data Store
        /// </summary>
        /// <history>
        ///     [cnurse]    02/13/2006  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void LoadSection()
        {
            if (SectionId != Null.NullInteger)
                Section = SectionController.GetSection(SectionId);
            else
                Section = new SectionInfo();
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The loadSections method gets the sections from the Data Store
        /// </summary>
        /// <history>
        ///     [cnurse]    03/30/2006  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void LoadSections()
        {
            Sections = SectionController.GetSections(this.ModuleId);

            if (SectionId < 0 && Sections.Count > 0)
            {
                SectionId = Sections[0].SectionId;
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The PublishArticle method runs when an Article is to be published
        /// </summary>
        /// <param name="saveArticle">The article to submit</param>
        /// <param name="comment">A comment</param>
        /// <history>
        /// 	[cnurse]	09/11/2007	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void PublishArticle(ArticleInfo saveArticle, string comment)
        {
            //Publish the Updated Article
            ArticleController.PublishArticle(saveArticle, comment, UserId);

            //Redirect back to page
            Response.Redirect(ReturnURL, true);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The RejectArticle method runs when an Article is to be rejected
        /// </summary>
        /// <param name="saveArticle">The article to reject</param>
        /// <param name="comment">A comment</param>
        /// <history>
        /// 	[cnurse]	09/11/2007	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void RejectArticle(ArticleInfo saveArticle, string comment)
        {
            //Reject the Updated Article
            ArticleController.RejectArticle(saveArticle, comment, UserId);

            //Redirect back to page
            Response.Redirect(ReturnURL, true);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The RestoreArticle method runs when an Article is to be restored
        /// </summary>
        /// <param name="saveArticle">The article to restore</param>
        /// <param name="comment">A comment</param>
        /// <history>
        /// 	[cnurse]	11/01/2007	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void RestoreArticle(ArticleInfo saveArticle, string comment)
        {
            //Restore the Article
            if (UseModeration)
                saveArticle.Status = PublishedStatus.Draft;
            else
                saveArticle.Status = PublishedStatus.Published;
            ArticleController.RestoreArticle(saveArticle, comment, UserId);

            //Redirect back to page
            Response.Redirect(ReturnURL, true);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The SaveArticle method runs when an Article is to be saved
        /// </summary>
        /// <history>
        /// 	[cnurse]	07/30/2006	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void SaveArticle(ArticleInfo saveArticle, string comment)
        {
            bool isValid = true;

            //Spin thru all the editors to make sure that the article is Valid
            //we have to do this as the editors can only determine if the field(s) they
            //support are valid or dirty
            foreach (ArticleEditor editor in ArticleEditors)
            {
                if (!editor.IsValid)
                {
                    isValid = false;
                    break;
                }
            }

            if (isValid)
            {
                if (IsAddMode)
                {
                    //Set the Module Id and PublishedStatus
                    saveArticle.ModuleId = this.ModuleId;
                    saveArticle.Status = (UseModeration) ? PublishedStatus.Draft : PublishedStatus.Published;

                    //Save the New Article
                    saveArticle.ArticleId = ArticleController.AddArticle(saveArticle, comment, UserId);
                }
                else
                {
                    if (saveArticle.Status == PublishedStatus.Published && UseModeration)
                    {
                        //Create new Version
                        saveArticle.VersionNo += 1;
                        ArticleController.AddNewVersion(saveArticle, comment, UserId);
                    }
                    else
                    {
                        //Save the Updated Article
                        ArticleController.UpdateArticle(saveArticle, comment, UserId);
                    }
                }

                //Redirect back to page
                Response.Redirect(ReturnURL, true);
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The SaveConfiguration method runs when the configuration is to be saved
        /// </summary>
        /// <history>
        /// 	[cnurse]	01/02/2008	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void SaveConfiguration(ArticleSettings settings)
        {
            settings.Configured = true;
            ArticleSettings.UpdateSettings(settings);

            //Redirect back to page
            Response.Redirect(ReturnURL, true);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The saveSection method runs when a Section is to be saved
        /// </summary>
        /// <history>
        /// 	[cnurse]	04/17/2006	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void SaveSection(SectionInfo saveSection)
        {
            if (IsAddMode)
            {
                //Set the Module Id
                saveSection.ModuleId = this.ModuleId;

                //Save the New Section
                saveSection.SectionId = SectionController.AddSection(saveSection, UserId);
            }
            else
                //Save the Updated Section
                SectionController.UpdateSection(saveSection, UserId);

            //Redirect back to page
            Response.Redirect(ReturnURL, true);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The SubmitArticle method runs when an Article is to be submitted
        /// </summary>
        /// <param name="saveArticle">The article to submit</param>
        /// <param name="comment">A comment</param>
        /// <history>
        /// 	[cnurse]	09/11/2007	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void SubmitArticle(ArticleInfo saveArticle, string comment)
        {
            //Submit the Updated Article
            ArticleController.SubmitArticle(saveArticle, comment, UserId);

            //Redirect back to page
            Response.Redirect(ReturnURL, true);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The ViewArticle method runs when an Article is to be viewed
        /// </summary>
        /// <history>
        /// 	[cnurse]	09/11/2007	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void ViewArticle()
        {
            //Load the ViewArticle Skin
            SetView(Constants.VIEW_ViewArticle);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The ViewModerateList method displays the list of articles awaiting moderation
        /// </summary>
        /// <history>
        ///     [cnurse]    10/29/2007  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void ViewModerateList()
        {
            if (HasModeratePermission)
            {
                //Load the Moderate View/Skin
                SetView(Constants.VIEW_Moderate);
            }
            else
                //Load the AccessDenied View
                SetView(Constants.VIEW_AccessDenied);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The ViewMyArticles method displays the list of articles for a creator user
        /// </summary>
        /// <history>
        ///     [cnurse]    10/29/2007  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void ViewMyArticles()
        {
            if (HasCreatePermission)
            {
                //Load the Moderate View/Skin
                SetView(Constants.VIEW_MyArticles);
            }
            else
                //Load the AccessDenied View
                SetView(Constants.VIEW_AccessDenied);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The ViewSection method displays the list of articles for a section
        /// </summary>
        /// <history>
        ///     [cnurse]    10/29/2007  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        private void ViewSection()
        {
            if (SectionId > Null.NullInteger)
            {
                //Set skin
                if (!String.IsNullOrEmpty(Section.SectionSkin))
                    SkinName = Section.SectionSkin;

                if (Articles != null && Articles.Count > 0)
                    //Load the ViewSection Skin
                    SetView(Constants.VIEW_ViewSection);
                else
                    if (IsEditable)
                        //Load the ViewSection Skin
                        SetView(Constants.VIEW_SectionIntro);
                    else
                        //Load the No Content Skin
                        SetView(Constants.VIEW_NoArticles);
            }
            else
            {
                //No Section or Article set
                if (Articles != null && Articles.Count > 0)
                    //Load the ViewSection Skin
                    SetView(Constants.VIEW_ViewSection);
                else
                {
                    if (IsEditable)
                        if (ArticleSettings.Configured)
                            SetView(Constants.VIEW_ModuleHelp);
                        else
                            ConfigureModule();
                    else
                        SetView(Constants.VIEW_ModuleIntro);
                }
            }
        }

        #endregion

        #region Protected Methods

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// CancelCommand runs when the cancel command button is clicked
        /// </summary>
        /// <param name="type">The entity type</param>
        /// <history>
        ///     [cnurse]  10/26/2007  created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected override void CancelCommand(string type)
        {
            switch (type)
            {
                case Constants.TYPE_Article:
                    CancelArticle();
                    break;
                case Constants.TYPE_Section:
                    CancelSection();
                    break;
            } 
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// DeleteCommand runs when the delete command button is clicked
        /// </summary>
        /// <param name="type">The entity type</param>
        /// <param name="entity">The entity</param>
        /// <param name="comment">A user submitted comment</param>
        /// <history>
        ///     [cnurse]  10/26/2007  created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected override void DeleteCommand(string type, object entity, string comment)
        {
            switch (type)
            {
                case Constants.TYPE_Article:
                    if (entity == null)
                        DeleteArticle();
                    else
                        DeleteArticle(entity as ArticleInfo);
                    break;
                case Constants.TYPE_Section:
                    DeleteSection();
                    break;
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Initializes the module
        /// </summary>
        /// <history>
        ///     [cnurse]  10/26/2007  created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected override void InitializeModule()
        {
            //Set the Resource File
            this.LocalResourceFile = Constants.LOCALIZATION_ResourceFile;

            //Get Ids from Querystring if first time to page
            // Get Article Id if set
            if (Request.QueryString[Constants.PARAM_ArticleId] != null)
            {
                int m_ArticleId = Int32.Parse(Request.QueryString[Constants.PARAM_ArticleId]);

                //First Check if we have the right TabModule Instance - we may not if we came
                //from Search as Search returns an arbitrary instance
                if (TabId != ViewTabId)
                {
                    //Redirect to the ViewTab
                    Response.Redirect(ArticleURL(ViewTabId));
                }
                ArticleId = m_ArticleId;

                //Set the section Id
                if (Article != null)
                    SectionId = Article.SectionId;
            }
            else
            {
                //Get Section Id if set
                if (Request.QueryString[Constants.PARAM_SectionId] != null)
                {
                    SectionId = Int32.Parse(Request.QueryString[Constants.PARAM_SectionId]);
                }
                else
                {
                    //No SectionId or ArticleId set
                    if (DefaultView == DefaultView.ViewSection)
                    {
                        SectionId = DefaultSection;
                    }
                    else
                    {
                        ArticleId = DefaultArticle;
                    }
                }
            } 
            
            //Call base class method
            base.InitializeModule();
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Initializes the modules view
        /// </summary>
        /// <history>
        ///     [cnurse]  10/26/2007  created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected override void InitializeView()
        {
            if (String.IsNullOrEmpty(Mode))
            {
                if (ArticleId > Null.NullInteger)
                    //Load the ViewArticle Skin
                    ViewArticle();
                else
                    //Load the ViewSection Skin
                    ViewSection();
            }
            else
            {
                switch (Mode)
                {
                    case Constants.KEY_AddArticle:
                        AddArticle();
                        break;
                    case Constants.KEY_AddSection:
                        EditSection();
                        break;
                    case Constants.KEY_EditArticle:
                        EditArticle();
                        break;
                    case Constants.KEY_EditSection:
                        EditSection();
                        break;
                    case Constants.KEY_ViewArticle:
                        ViewArticle();
                        break;
                    case Constants.KEY_ViewSection:
                        ViewSection();
                        break;
                    case Constants.KEY_Moderate:
                        ViewModerateList();
                        break;
                    case Constants.KEY_MyArticles:
                        ViewMyArticles();
                        break;
                    default:
                        SetView(Mode);
                        break;
                }
            }

            //Runs base class method
            base.InitializeView();
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The ProcessSkinObject method attaches events to the SkinObjects in this Skin
        /// </summary>
        /// <param name="skinObject">SkinObject to process</param>
        /// <history>
        ///     [cnurse]    10/26/2007  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected override void ProcessSkinObject(ISkinObject skinObject)
        {
            if (skinObject is ArticleEditor)
            {
                ArticleEditor editorObject = (ArticleEditor)skinObject;
                AddArticleEditor(editorObject);
            }
            if (skinObject is SectionEditor)
            {
                SectionEditor editorObject = (SectionEditor)skinObject;
                AddSectionEditor(editorObject);
            }
            if (skinObject is SettingsEditor)
            {
                SettingsEditor editorObject = (SettingsEditor)skinObject;
                AddSettingsEditor(editorObject);
            }

            //Call base method to process base class SkinObjects
            base.ProcessSkinObject(skinObject);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// PublishCommand runs when the publish command button is clicked
        /// </summary>
        /// <param name="type">The entity type</param>
        /// <param name="entity">The entity</param>
        /// <param name="comment">A user submitted comment</param>
        /// <history>
        ///     [cnurse]  10/26/2007  created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected override void PublishCommand(string type, object entity, string comment)
        {
            if (type == Constants.TYPE_Article)
                PublishArticle(entity as ArticleInfo, comment);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// RejectCommand runs when the reject command button is clicked
        /// </summary>
        /// <param name="type">The entity type</param>
        /// <param name="entity">The entity</param>
        /// <param name="comment">A user submitted comment</param>
        /// <history>
        ///     [cnurse]  10/26/2007  created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected override void RejectCommand(string type, object entity, string comment)
        {
            if (type == Constants.TYPE_Article)
                RejectArticle(entity as ArticleInfo, comment);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// RestoreCommand runs when the restore command button is clicked
        /// </summary>
        /// <param name="type">The entity type</param>
        /// <param name="entity">The entity</param>
        /// <param name="comment">A user submitted comment</param>
        /// <history>
        ///     [cnurse]  11/01/2007  created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected override void RestoreCommand(string type, object entity, string comment)
        {
            if (type == Constants.TYPE_Article)
                RestoreArticle(entity as ArticleInfo, comment);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// SaveCommand runs when the save/update command button is clicked
        /// </summary>
        /// <param name="type">The entity type</param>
        /// <param name="entity">The entity</param>
        /// <param name="comment">A user submitted comment</param>
        /// <history>
        ///     [cnurse]  10/26/2007  created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected override void SaveCommand(string type, object entity, string comment)
        {
            switch (type)
            {
                case Constants.TYPE_Article:
                    SaveArticle(entity as ArticleInfo, comment);
                    break;
                case Constants.TYPE_Section:
                    SaveSection(entity as SectionInfo);
                    break;
                case Constants.TYPE_Settings:
                    SaveConfiguration(entity as ArticleSettings);
                    break;
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// SubmitCommand runs when the submit command button is clicked
        /// </summary>
        /// <param name="type">The entity type</param>
        /// <param name="entity">The entity</param>
        /// <param name="comment">A user submitted comment</param>
        /// <history>
        ///     [cnurse]  10/26/2007  created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected override void SubmitCommand(string type, object entity, string comment)
        {
            if (type == Constants.TYPE_Article)
                SubmitArticle(entity as ArticleInfo, comment);
        }

        #endregion

        #region Public Methods 

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// ArticleURL builds the url for links
        /// </summary>
        /// <param name="mode">The mode of the module</param>
        /// <returns>The Url as a string</returns>
        /// <history>
        /// 	[cnurse]	10/30/2007	created
        /// </history>
        /// -----------------------------------------------------------------------------
        public string ArticleURL(string mode)
        {
            return ArticleURL(TabId, Null.NullInteger, Null.NullInteger, mode, true);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// ArticleURL builds the url for links
        /// </summary>
        /// <param name="tabId">The Id of the Tab/Page</param>
        /// <returns>The Url as a string</returns>
        /// <history>
        /// 	[cnurse]	10/30/2007	created
        /// </history>
        /// -----------------------------------------------------------------------------
        public string ArticleURL(int tabId)
        {
            return ArticleURL(tabId, Null.NullInteger, Null.NullInteger, Null.NullString, true);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// ArticleURL builds the url for links
        /// </summary>
        /// <param name="tabId">The Id of the Tab/Page</param>
        /// <param name="articleId">The Id of the Article</param>
        /// <param name="mode">The mode of the module</param>
        /// <returns>The Url as a string</returns>
        /// <history>
        /// 	[cnurse]	10/30/2007	created
        /// </history>
        /// -----------------------------------------------------------------------------
        public string ArticleURL(int tabId, int articleId, string mode)
        {
            return ArticleURL(tabId, articleId, Null.NullInteger, mode, false);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// ArticleURL builds the url for links
        /// </summary>
        /// <param name="tabId">The Id of the Tab/Page</param>
        /// <param name="articleId">The Id of the Article</param>
        /// <param name="sectionId">The Id of the Section</param>
        /// <param name="mode">The mode of the module</param>
        /// <returns>The Url as a string</returns>
        /// <history>
        /// 	[cnurse]	10/30/2007	created
        /// </history>
        /// -----------------------------------------------------------------------------
        public string ArticleURL(int tabId, int articleId, int sectionId, string mode)
        {
            return ArticleURL(tabId, articleId, sectionId, mode, false);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// ArticleURL builds the url for links
        /// </summary>
        /// <param name="tabId">The Id of the Tab/Page</param>
        /// <param name="articleId">The Id of the Article</param>
        /// <param name="sectionId">The Id of the Section</param>
        /// <param name="mode">The mode of the module</param>
        /// <param name="ignoreScope">A flag that determines whether to ignore the current scope</param>
        /// <returns>The Url as a string</returns>
        /// <history>
        /// 	[cnurse]	10/30/2007	created
        /// </history>
        /// -----------------------------------------------------------------------------
        public string ArticleURL(int tabId, int articleId, int sectionId, string mode, bool ignoreScope)
        {
            string param = Null.NullString;

            if (!ignoreScope)
            {
                if (!String.IsNullOrEmpty(Mode) && Mode != mode)
                {
                    if (String.IsNullOrEmpty(Scope))
                    {
                        param += Constants.PARAM_Scope + "=" + Mode;
                    }
                    else
                    {
                        param += Constants.PARAM_Scope + "=" + Scope + "_" + Mode;
                    }
                }
            }

            if (!String.IsNullOrEmpty(param))
                param += "&";
            param += Constants.PARAM_Mode + "=" + mode;

            if (sectionId > Null.NullInteger)
                param += "&" + Constants.PARAM_SectionId + "=" + sectionId.ToString();

            if (articleId > Null.NullInteger)
                param += "&" + Constants.PARAM_ArticleId + "=" + articleId.ToString();

            return Globals.NavigateURL(tabId, "", param);

        }

        #endregion

        #region Event Handlers

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// moduleAction handles a module action that occurs
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <history>
        /// 	[anurse]	1/14/2006	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected override void ModuleAction(Object sender, ActionEventArgs e)
        {
            switch (e.Action.CommandName)
            {
                case Constants.ACTION_DeleteSection:
                    DeleteSection();
                    break;
                case Constants.ACTION_DeleteArticle:
                    DeleteArticle();
                    break;
                default:
                    break;
            }

            //call base class method to manage base class actions
            base.ModuleAction(sender, e);
        }

        #endregion

    }
}
